/******************************************************************************
 * Copyright (C) 2017 Chengdu Dlhd information industry co. LTD.
 * All Rights Reserved.
 * 本软件为成都顶联互动信息产业有限公司开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、复制、修改或发布本软件.
 *****************************************************************************/
package net.dgg.dggcloud.service.jrcrm.service.cms;

import net.dgg.dggcloud.core.constants.Constants;
import net.dgg.dggcloud.core.util.DateUtil;
import net.dgg.dggcloud.core.util.StringUtils;
import net.dgg.dggcloud.service.common.base.service.BaseService;
import net.dgg.dggcloud.service.common.exception.BizException;
import net.dgg.dggcloud.service.jrcrm.common.webscoket.MsgPublisher;
import net.dgg.dggcloud.service.jrcrm.dao.cms.MessageDao;
import net.dgg.dggcloud.service.jrcrm.dao.cms.MessageReadyDao;
import net.dgg.dggcloud.service.jrcrm.entity.cms.Message;
import net.dgg.dggcloud.service.jrcrm.entity.cms.MessageReady;
import net.dgg.dggcloud.service.jrcrm.entity.cms.MessageTemplate;
import net.dgg.dggcloud.service.entity.user.User;
import net.dgg.dggcloud.service.service.organization.OrganizationService;
import net.dgg.dggcloud.service.service.user.UserService;
import net.dgg.framework.tac.mq.rabbitmq.queue.DggMessageSendUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author duqian
 * @ClassName: MessageService
 * @Description: 信息逻辑类
 * @date 2017年11月06日11:30:00
 */
@Service
public class MessageService extends BaseService {
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private SmsRecordService smsRecordService;
    @Autowired
    private MessageTemplateService messageTemplateService;
    @Autowired
    private MessageReadyService messageReadyService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private UserService userService;
//    @Autowired
//    private MessageManager messageManager;
    private static String messageQueName="net.dgg.dggcloud.jrcrm.backservice.common.mq.MessageConsumer";

    /**
     * 查询站内信或预警
     *
     * @param map 查询条件：receiverId 接收人id </br>
     *            mesType 类型 1站内信 2预警信息 </br>
     *            readFlag 是否读 0未读 1读 </br>
     * @return
     */
    public List<Map> listMessageByMap(Map map) {
        return messageDao.listMessageByMap(map);
    }

    public Integer countMessageByMap(Map map) {
        return messageDao.countMessageByMap(map);
    }

    /**
     * 发送消息
     *
     * @param receiverUser 接收人
     * @param sendUser     发送人
     * @param content      内容
     * @param msgType      类型 1普通消息，2重要消息
     */
    public void sendMessage(User receiverUser, User sendUser, String content, Integer msgType,String audioType) {
        if (null != receiverUser && StringUtils.isNotEmpty(content)) {
            Message message = new Message();
            message.setId(keyWorker.nextId());
            message.setReceiverId(receiverUser.getId());
            message.setMesType(null == msgType ? 1 : msgType);
            message.setContent(content);
            message.setReadFlag(0);
            message.setSendStatus(0);
            message.setCreateUser(sendUser);
            message.setAudioType(audioType);
            this.repository.saveOrUpdate(message);
            MsgPublisher.getInstance().publish(receiverUser.getId(), content, message);
        }

    }


    /**
     * 通过消息模版发送消息(及时)
     *
     * @param receiverUser        接收人
     * @param sendUser            发送人
     * @param vals                模版：【{0}】的商机【{1}】因为【{2}】在【{3}】已掉库
     *                            参数：
     *                            String[] vals = {"张三", "SJ201711184555", "超期跟进", "2017-11-12 15:55"};
     *                            或： String[] vals = new String[3];
     *                            vals[0]="张三";
     *                            vals[1]="SJ201711184555";
     *                            vals[2]="超期跟进";
     *                            vals[3]="2017-11-12 15:55";
     *                            效果：【张三】的商机【SJ201711184555】因为【超期跟进】在【17-11-16 下午7:32】已掉库
     * @param messageTemplateCode 消息模版code
     */
    public void sendMessage1(User receiverUser, User sendUser, String[] vals, String messageTemplateCode) {
        try {
            if (null != receiverUser && StringUtils.isNotEmpty(messageTemplateCode) && null != vals) {
                MessageTemplate messageTemplate = messageTemplateService.getMessageTemplateByCode(messageTemplateCode);
                if (null != messageTemplate && 1 == messageTemplate.getStatus()) {
                    //模版内容
                    String tempContent = messageTemplate.getContent();
                    //获取模版参数个数
                    MessageFormat messageFormat = new MessageFormat(tempContent);
                    int messageTempLength = messageFormat.getFormatsByArgumentIndex().length;

                    //获取入参个数
                    int valsLength = vals.length;
                    //判断入参个数与模版参数个数是否一样
                    if (messageTempLength == valsLength) {
                        //推送方式
                        String pushType = messageTemplate.getPushType();
                        boolean pushTypeSms = false,//是否发送短信
                                pushTypeGeneral = false,//是否发送重点消息
                                pushTypeImportant = false;//是否发送普通消息
                        if (StringUtils.isNotEmpty(pushType)) {
                            pushTypeSms = pushType.contains("PUSH_TYPE_1");//获取推送方式中有无发送短信
                            pushTypeGeneral = pushType.contains("PUSH_TYPE_2");//获取推送方式中有无发送重点消息
                            pushTypeImportant = pushType.contains("PUSH_TYPE_3");//获取推送方式中有无发送普通消息
                        }

                        //推送对象
                        String pushObject = messageTemplate.getPushObject();
                        String audioType = messageTemplate.getAudioType();
                        boolean pushObjectSelf = false,//是否推送给当事人
                                pushObjectLeader = false,//是否推送给直管领导
                                pushObjectTopLeader = false,//是否推送给上上级领导
                                pushObjectBugOrgLeader = false;//是否推送给事业部总经理
                        if (StringUtils.isNotEmpty(pushObject)) {
                            pushObjectSelf = pushObject.contains("PUSH_OBJECT_1");//获取推送对象中有无当事人
                            pushObjectLeader = pushObject.contains("PUSH_OBJECT_2");//获取推送对象中有无直管领导
                            pushObjectTopLeader = pushObject.contains("PUSH_OBJECT_3");//获取推送对象中有无上上级领导
                            pushObjectBugOrgLeader = pushObject.contains("PUSH_OBJECT_4");//获取推送对象中有无事业部总经理
                        }
                        //判断有无可推送方式和可推送对象
                        if ((pushTypeSms || pushTypeGeneral || pushTypeImportant) && (pushObjectSelf || pushObjectLeader || pushObjectTopLeader || pushObjectBugOrgLeader)) {
                            String msgContent = messageFormat.format(vals);
                            //去掉占位符
                            msgContent = msgContent.replaceAll(Constants.MESSAGE_READY_EMPTY_TAG,"-");
                            //发送给当事人
                            if (pushObjectSelf) {
                                this.sendMessageByPushType(receiverUser, sendUser, msgContent, pushTypeSms, pushTypeGeneral, pushTypeImportant,audioType);
                            }
                            //判断部门是否为空
                            if (null != receiverUser.getOrgId()) {

                                Map params = new HashMap();
                                params.put("organizationId", receiverUser.getOrgId());
                                List<Map> map = organizationService.getAncestors(params);
                                //发送给上级领导
                                if (pushObjectLeader) {
                                    receiverUser = null;
                                    Map mapOrg = map.get(0);
                                    Long leaderId=null!=mapOrg.get("leaderid")?Long.parseLong(mapOrg.get("leaderid").toString()):null;
                                    if(null!=leaderId){
                                        receiverUser = userService.getUserById(leaderId);
                                        this.sendMessageByPushType(receiverUser, sendUser, msgContent, pushTypeSms, pushTypeGeneral, pushTypeImportant,audioType);
                                    }
                                }
                                //发送给上上级领导
                                if (pushObjectTopLeader) {
                                    receiverUser = null;
                                    Map mapOrg = map.get(1);
                                    Long leaderId=null!=mapOrg.get("leaderid")?Long.parseLong(mapOrg.get("leaderid").toString()):null;
                                    if(null!=leaderId){
                                        receiverUser = userService.getUserById(leaderId);
                                        this.sendMessageByPushType(receiverUser, sendUser, msgContent, pushTypeSms, pushTypeGeneral, pushTypeImportant,audioType);
                                    }
                                }
                                //发送给事业部总经理
                                if (pushObjectBugOrgLeader) {
                                    receiverUser = null;
                                    Map mapOrg = map.get(2);
                                    Long leaderId=null!=mapOrg.get("leaderid")?Long.parseLong(mapOrg.get("leaderid").toString()):null;
                                    if(null!=leaderId){
                                        receiverUser = userService.getUserById(leaderId);
                                        this.sendMessageByPushType(receiverUser, sendUser, msgContent, pushTypeSms, pushTypeGeneral, pushTypeImportant,audioType);
                                    }
                                }
                            }
                        } else {
                            logger.error("未找到可推送方式或推送对象，检查是否设置了短信模版相关内容");
                        }
                    } else {
                        logger.error("vals参数不匹配，检查入参个数与模版参数个数是否一样");
                    }
                } else {
                    logger.error("根据CODE未找到可用消息模版，或消息模版禁用");
                }
            } else {
                logger.error("有参数为空");
            }
        } catch (Exception e) {
        }
    }


    /**
     * 发送不同推送类型的消息
     *
     * @param receiverUser      接收人
     * @param sendUser          发送人
     * @param content           内容
     * @param pushTypeSms       发送短信
     * @param pushTypeGeneral   发送普通消息
     * @param pushTypeImportant 发送重要消息
     */
    public void sendMessageByPushType(User receiverUser, User sendUser, String content, boolean pushTypeSms, boolean pushTypeGeneral, boolean pushTypeImportant,String audioType) {
        if (null != receiverUser && StringUtils.isNotEmpty(content)) {
            //发送短信
            if (pushTypeSms) {
                //发送短信需处理掉html标签
                smsRecordService.sendMsg(receiverUser.getPhone(), StringUtils.delHtmlTag(content), receiverUser.getName(), sendUser);
            }
            //发送普通消息
            if (pushTypeGeneral) {
                this.sendMessage(receiverUser, sendUser, content, 1,audioType);
            }
            //发送重要消息
            if (pushTypeImportant) {
                this.sendMessage(receiverUser, sendUser, content, 2,audioType);
            }
        }
    }

    /**
     * 通过消息模版发送消息(待发送)
     *
     * @param receiverUser        接收人Id
     * @param sendUser            发送人Id
     * @param vals                模版：【{0}】的商机【{1}】因为【{2}】在【{3}】已掉库
     *                            参数：
     *                            String[] vals = {"张三", "SJ201711184555", "超期跟进", "2017-11-12 15:55"};
     *                            或： String[] vals = new String[3];
     *                            vals[0]="张三";
     *                            vals[1]="SJ201711184555";
     *                            vals[2]="超期跟进";
     *                            vals[3]="2017-11-12 15:55";
     *                            效果：【张三】的商机【SJ201711184555】因为【超期跟进】在【17-11-16 下午7:32】已掉库
     * @param messageTemplateCode 消息模版code
     */
    public void sendMessageReady(User receiverUser, User sendUser, String[] vals, String messageTemplateCode) {
        try {
            if (null == receiverUser) {
                throw new BizException(" 接收人为空", 10001);
            }
            if (null == vals) {
                throw new BizException("参数为空", 10001);
            }
            if (StringUtils.isEmpty(messageTemplateCode)) {
                throw new BizException("消息模版编码为空", 10001);
            }
            for (int i = 0; i <vals.length ; i++) {
                if(StringUtils.isEmpty(vals[i])){
                    vals[i]="##";
                }
            }
            MessageReady messageReady = new MessageReady();
            messageReady.setId(keyWorker.nextId());
            messageReady.setReceiverId(receiverUser.getId());
            messageReady.setCreateUser(sendUser);
            messageReady.setStatus(1);
            messageReady.setTemplateCode(messageTemplateCode);
            messageReady.setVals(StringUtils.join(vals, "^"));
            DggMessageSendUtil.putMessage(messageQueName,messageReady );
          // messageReadyService.saveMessageReady(messageReady);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 查询最新重要消息一条通过用户id
     * @param userId
     * @return
     */
    public List<Map> queryMajorMessageByUserId(Long userId) {
        Map map=new HashMap();
        map.put("userId",userId);
        map.put("mesType",Message.MES_TYPE_WARN);//重要标示
        map.put("readFlag",Message.READ_FLAG_NO);//未读状态
        List<Map> maps = messageDao.queryMajorMessageByMap(map);
        return maps;
    }

    /**
     * 查询最新10条普通消息通过用户id
     * @param userId
     * @return
     */
    public List<Map> queryCommonMessageByMap(Long userId) {
        Map map=new HashMap();
        map.put("userId",userId);
        map.put("mesType",Message.MES_TYPE_MAIL);//重要标示
        map.put("readFlag",Message.READ_FLAG_NO);//未读状态
        return messageDao.queryCommonMessageByMap(map);
    }


    /**
     * 更新消息为已读状态
     * @param messageId
     */
    public void updateReadFlagOfMessage(String messageId,User user) {
        try {
            Message message = this.repository.get(Message.class, Long.parseLong(messageId));
            message.setReadFlag(Message.READ_FLAG_YES);
            message.setUpdaterUser(user);
            message.setReadTime(new Date());
            this.repository.saveOrUpdate(message);
        }catch (Exception e){
            e.printStackTrace();
            throw new BizException("消息更新为已读异常"+e.getMessage(),10006);
        }


    }

    /**
     * 批量更新消息为已读
     * @param messagesId:消息id </br>
     * @param user：当前用户 </br>
     */
    @Transactional
    public void batchUpdateReadFlagOfMessages(String messagesId, User user) {
        try {
            Map map=new HashMap();
            map.put("ids",messagesId);
            map.put("readFlag",Message.READ_FLAG_YES);//读取标志
            String currentDate = DateUtil.dateToString(new Date());
            map.put("updateTime", currentDate);
            map.put("updaterId",user.getId());
            map.put("updaterName",user.getName() + user.getLoginName());
            map.put("readTime",currentDate);
            map.put("updaterOrgId",user.getOrgId());
            messageDao.batchUpdateReadFlagByMap(map);
        }catch (Exception e){
            e.printStackTrace();
            throw new BizException("消息更新为已读异常"+e.getMessage(),10006);
        }

    }
}
